package cruncher;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Map.Entry;

import logic.PlayfairCipher;

public class DigraphMap {
	private HashMap<String, Integer> digraphs = new HashMap<String, Integer>();
	private ArrayList<Entry<String, Integer>> entList = null;
	private PlayfairCipher cipher = null;
	
	public DigraphMap(PlayfairCipher cipher)
	{
		this.cipher = cipher;
	}
	
	public DigraphMap(PlayfairCipher cipher, String fileName)
	{
		this.cipher = cipher;
		loadFromFile(fileName);
	}
	
	private void putDigraph(String digraph)
	{
		if(digraphs.containsKey(digraph))
		{
			digraphs.put(digraph, digraphs.get(digraph) + 1);
		}
		else
		{
			digraphs.put(digraph, 1);
			//System.out.println("Word added : " + word);
		}
	}
	
	public void crunch(String text)
	{
		text = text.toLowerCase();
		text = cipher.sanitizeString(text);
		text = cipher.getLanguage().doMappings(text);
		char[] cs = text.toCharArray();
		
		for(int i = 0; i < cs.length; i += 2)
		{
			putDigraph(text.substring(i, i + 2));
		}
	}
	
	private void loadFromFile(String fileName)
	{
		try {
			Scanner s = new Scanner(new File(fileName));
			
			while(s.hasNext())
			{
				digraphs.put(s.next(), s.nextInt());
			}
			
			s.close();
			updateList();
		} catch (FileNotFoundException e) {
			System.out.println("Can't load file : " + fileName);
		}
	}
	
	public void saveToFile(String fileName)
	{
		try {
			PrintWriter pw = new PrintWriter(new File(fileName));
			updateList();
			
			for(Map.Entry<String, Integer> entry : entList)
			{
				pw.println(entry.getKey() + " " + entry.getValue());
			}
			
			pw.close();
		} catch (FileNotFoundException e) {
			System.out.println("Can't save file : " + fileName);
		}
	}
	
	public String getDigraph(int i)
	{
		return entList.get(i).getKey();
	}
	
	public int getNumDigraphs()
	{
		return entList.size();
	}
	
	public void crunchFile(String fileName)
	{
		try {
			Scanner s = new Scanner(new File(fileName));
			while(s.hasNext())
				crunch(s.nextLine());
			s.close();
		} catch (FileNotFoundException e) {
			System.out.println("Error opening file : " + fileName);
		}
		updateList();
	}
	
	private void updateList()
	{
		entList = new ArrayList<Map.Entry<String,Integer>>(digraphs.entrySet());
		Collections.sort(entList, new Comparator<Entry<String, Integer>>() {

			@Override
			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				return o2.getValue() - o1.getValue();
			}
		});
	}
	
	public void printContent()
	{
		if(entList == null) updateList();
		for(Map.Entry<String, Integer> entry : entList)
		{
			System.out.println(entry.getValue() + " : " + entry.getKey());
		}
	}
	
	public int evaluate(String text)
	{
		int score = 0;
		
		/*
		for(Map.Entry<String, Integer> entry : entList)
		{
			int sind = -1;
			int count = 0;
			do
			{
				sind++;
				//sind = text.indexOf(entry.getKey(), sind);
				sind = text.indexOf(entry.getKey(), sind);
				if(sind > 0) count++;
			} while(sind >= 0);
			score += count * entry.getKey().length() * 2;
			
			//score += count; // * word.length() * word.length();
			//System.out.println("Score : " + score);
		}
		*/
		return score;
	}
}
